Jvm如何内存调优? | 您所在的位置:网站首页 › jvm 占用内存 › Jvm如何内存调优? |
身为一个Java开发人员,想必对Jvm都不陌生,Java程序跑在Jvm中,但是Jvm是如何让我们的程序跑的高效的呢?我们又该如何去做内存调优呢,今天一起来和大家探讨下。 JVM 经过这么多年的发展和验证,整体是非常健壮的。个人认为99%的情况下,基本用不到 JVM 调优。通常来说,我们的 JVM 参数配置大多还是会遵循 JVM 官方的建议,例如: -XX:NewRatio=2,年轻代:老年代=1:2 -XX:SurvivorRatio=8,eden:survivor=8:1 堆内存设置为物理内存的3/4左右 等等 JVM 参数的默认(推荐)值都是经过 JVM 团队的反复测试和前人的充分验证得出的比较合理的值,因此通常来说是比较靠谱和通用的,一般不会出大问题。 当然,更重要的是,大部分的应用 QPS 都不到10,数据量不到几万,这种低压环境下,想让 JVM 出问题,说实话也挺难的。 那么还需要内存调优吗? 俗话说得好,凡事无绝对,还是有一小部分场景,是可能需要用到 JVM 调优的。具体哪些场景,我们在下面介绍。 值得一提的是,我们这边所说的 JVM 调优更多的是针对自己的业务场景对 JVM 参数进行优化调整,使其更适合我们的业务,而不是指对 JVM 源码的改动。 Jvm何时优化?忌过早优化。《计算机程序设计艺术》的作者高德纳(Donald Ervin Knuth)曾说过一句经典的话: The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.真正的问题是,程序猿在错误的地方和错误的时间花了太多的时间担心效率问题;过早的优化是编程中所有(或者至少是大部分)罪恶的根源。 忌过早并不是说就完全不管,比较正确的做法应该是给核心服务的一些重要 JVM 指标配上监控告警,当指标出现波动或者异常时,能及时介入排查。 Jvm优化步骤分析和定位当前系统的瓶颈 对于JVM的核心指标,我们的关注点和常用工具如下: 1)CPU指标查看占用CPU最多的进程 查看占用CPU最多的线程 查看线程堆栈快照信息 分析代码执行热点 查看哪个代码占用CPU执行时间最长 查看每个方法占用CPU时间比例 常见的命令: // 显示系统各个进程的资源使用情况 top // 查看某个进程中的线程占用情况 top -Hp pid // 查看当前 Java 进程的线程堆栈信息 jstack pid常见的工具:JProfiler、JVM Profiler、Arthas等。 2)JVM 内存指标查看当前 JVM 堆内存参数配置是否合理 查看堆中对象的统计信息 查看堆存储快照,分析内存的占用情况 查看堆各区域的内存增长是否正常 查看是哪个区域导致的GC 查看GC后能否正常回收到内存 常见的命令: // 查看当前的 JVM 参数配置 ps -ef | grep java // 查看 Java 进程的配置信息,包括系统属性和JVM命令行标志 jinfo pid // 输出 Java 进程当前的 gc 情况 jstat -gc pid // 输出 Java 堆详细信息 jmap -heap pid // 显示堆中对象的统计信息 jmap -histo:live pid // 生成 Java 堆存储快照dump文件 jmap -F -dump:format=b,file=dumpFile.phrof pid常见的工具:Eclipse MAT、JConsole等。 3)JVM GC指标查看每分钟GC时间是否正常 查看每分钟YGC次数是否正常 查看FGC次数是否正常 查看单次FGC时间是否正常 查看单次GC各阶段详细耗时,找到耗时严重的阶段 查看对象的动态晋升年龄是否正常 JVM 的 GC指标一般是从 GC 日志里面查看,默认的 GC 日志可能比较少,我们可以添加以下参数,来丰富我们的GC日志输出,方便我们定位问题。 GC日志常用 JVM 参数: // 打印GC的详细信息 -XX:+PrintGCDetails // 打印GC的时间戳 -XX:+PrintGCDateStamps // 在GC前后打印堆信息 -XX:+PrintHeapAtGC // 打印Survivor区中各个年龄段的对象的分布信息 -XX:+PrintTenuringDistribution // JVM启动时输出所有参数值,方便查看参数是否被覆盖 -XX:+PrintFlagsFinal // 打印GC时应用程序的停止时间 -XX:+PrintGCApplicationStoppedTime // 打印在GC期间处理引用对象的时间(仅在PrintGCDetails时启用) -XX:+PrintReferenceGC以上就是我们定位系统瓶颈的常用手段,大部分问题通过以上方式都能定位出问题原因,然后结合代码去找到问题根源。 |
CopyRight 2018-2019 实验室设备网 版权所有 |